import Vue from 'vue';
import { run } from './launcher.js';
import { extend, extendHtml, htmlToText, each, deleteNullValue, upcaseFirstChar } from 'cloudbase-components/src/utils';
import { AllowedRouters } from './store';
import { getDict, getDicts, setDict, setDicts } from './dict-cache';
import { isRouterPass } from './routers';

import { 
	getInitData, logout, 
	hasRoles, hasPerms, 
	getSimpleDict, getMultiDicts, 
	setUserSetting, getUserSetting, getUserSettings,
	URI_DOWNLOAD
} from './api';

//当前菜单数据字典值
let currentMenuType = "MENU-TYPE-SYSTEM";

export { currentMenuType, extend, extendHtml, htmlToText, each, deleteNullValue, upcaseFirstChar };

//打开方式
export const EMBED_QIANKUN = 'qiankun';
export const EMBED_IFRAME = 'iframe';
export const LINK_SELF = 'link';
export const LINK_BLANK = 'blank';

//窗口默认配置
const defaultFrameOptions = {
	width: 800,
	height: 500,
	embed: '',
	footer: false,
	mask: true,
	transparent: false,
	animateIn: "zoomIn",
	animateOut: "zoomOut",
	callback() {},
	onFrameClose() {},
	onGetFrame(frame) {}
};

let frameId = 0;

const $ = {

	commonModal(method, msg, callback, loading) {
		callback = callback || function() {};
		var options = {
			title:this.$t("info.title"),
			content: this.$t(msg),
			loading:loading,
			okText:this.$t("info.ok"),
			onOk:function() {
				return callback.call(this);
			}
		};
		return this.$Modal[method](options);
	},
	alert(msg, callback, loading) {
		return $.commonModal("warning", msg, callback, loading);
	},
	info(msg, callback, loading) {
		return $.commonModal("info", msg, callback, loading);
	},
	success(msg, callback, loading) {
		return $.commonModal("success", msg, callback, loading);
	},
	error(msg, callback, loading) {
		return $.commonModal("error", msg, callback, loading);
	},
	confirm(msg, callback, loading) {
		callback = callback || function() {};
		var options = {
			title: this.$t("info.title"),
			content: this.$t(msg),
			loading: loading,
			cancelText:this.$t("info.cancel"),
			okText:this.$t("info.ok"),
			onOk:function() {
				return callback.call(this, true);
			},
			onCancel:function() {
				return callback.call(this, false);
			}
		};
		return this.$Modal.confirm(options);
	},
	msg(method, args) {
		var me = this.$Message;
		return this.$Message[method].apply(me, args);
	},
	minfo() {
		return $.msg("info", arguments);
	},
	msuccess() {
		return $.msg("success", arguments);
	},
	mwarning() {
		return $.msg("warning", arguments);
	},
	merror() {
		return $.msg("error", arguments);
	},
	mloading() {
		return $.msg("loading", arguments);
	},
	location(router, params = {}, embed='') {
		if(embed == EMBED_QIANKUN) {
			params.link = router;
			params.id = nextFrameId();
			this.$router.push({
				name: EMBED_NAME,
				params
			});
		} else if(embed == EMBED_IFRAME) {
			params.link = router;
			params.id = nextFrameId();
			this.$router.push({
				name: IFRAME_NAME,
				params
			});
		} else {
			this.$router.push({
				path: fillRouter(router), 
				params
			});
		}
	},
	showGlobalError(error) {
		this.$Message.error(this.$t(error));
	},
	init() {
		getInitData(currentMenuType, (res) => {
			this.$store.commit('init', res);
        	$.runLaunchers(res);
		});
	},
	uninit() {
		this.$store.commit("init", { success: false });
	},
	runLaunchers(res) {
		if(res.success && res.data.launchers) {
			run(res.data.launchers);
		}
	},
    fit(container, dataWithHeight) {
    	var containerDom = container.$el || container;
    	var iframe = document.createElement("iframe");
    	iframe.border = '0';
    	iframe.style = "position:absolute;border:0;z-index:-1;left:0;top:0;width:100%;height:100%;";
    	iframe.onload = () => {
    		var content = iframe.contentWindow;
	    	content.onresize = function() {
	    		if(dataWithHeight) {
					dataWithHeight.height = content.document.body.clientHeight || content.document.documentElement.clientHeight;
				}
	    	}
	    	content.onresize();
    	}
    	if(containerDom.append) {
    		containerDom.append(iframe);
    	} else {
    		containerDom.appendChild(iframe);
    	}
	},
	yesOrNoRender(h, params) {
		var value = params.row[params.column.key];
	    return h('span', {
	    	style: {
	    		color: value ? "#19be6b" : "#ed4014"
	    	}
	    }, value ? this.$t("info.yes") : this.$t("info.no"));
	},
	createWindow(options) {
		if(options.router) {
			if(!isRouterPass(options.router)) {
				console.log("没有权限访问：" + options.router);
				return;
			}
			const opts = {};
			extend(opts, defaultFrameOptions, options);
			const qiankun = opts.embed == EMBED_QIANKUN;
			const iframe = opts.embed == EMBED_IFRAME;
			const routerName = qiankun ? EMBED_NAME : iframe ? IFRAME_NAME : getRouterName(options.router);
			const router = qiankun ? EMBED_ROUTER : iframe ? IFRAME_ROUTER : fillRouter(options.router);
			if(!opts.component) {
				opts.component = routerName;
			}
			opts.id = nextFrameId();
			if(qiankun) {
				if(!opts.params) {
					opts.params = {};
				}
				opts.params.id = `${EMBED_NAME}-${opts.id}`;
				opts.params.link = options.router;
			} else if(iframe) {
				if(!opts.params) {
					opts.params = {};
				}
				opts.params.id = `${IFRAME_NAME}-${opts.id}`;
				opts.params.link = options.router;
			}
			if(Vue.component(routerName)) {
				//已经加载过组件
				this.addFrame(opts);
			} else {
				//加载组件
				loadRouterComponent(this.$router, routerName, (route) => {
	                return route.path == router || (qiankun && route.path == EMBED_ROUTER) || (iframe && route.path == IFRAME_ROUTER);
	            }, (success) => {
	            	if(success) {
	            		this.addFrame(opts);
	            	} else {
	            		const devName = "Dev";
	            		opts.component = devName;
		            	if(Vue.component(devName)) {
		            		//已经加载过组件
							this.addFrame(opts);
		            	} else {
		            		//加载组件
		            		loadRouterComponent(this.$router, devName, (route) => {
				                return route.path == '*';
				            }, (isOk) => {
				            	if(isOk) {
				            		this.addFrame(opts);
				            	}
				            });
		            	}
	            	}
	            });
	        }
		}
	},
	profile() {
		createWindow({
			title: this.$t("profile.title"),
			router: "/sys/profile",
			width: 600,
			resizable: false,
			max: false,
			animateIn: "bounceInDown",
			animateOut: "bounceOutUp"
		});
	},
	exit() {
		var _this = this;
		confirm("info.confirm.exit", function (isOk) {
			if(isOk) {
				var me = this;
				logout((res) => {
					me.remove();
					if(res.success) {
						_this.$store.commit("init", { success: false });
					}
				});
				return false;
			}
		}, true);
	}
};

export const loadRouterComponent = ($router, routerName, filter = (route) => false, callback = function() {}) => {
	var routes = $router.getRoutes().filter(filter);
    if(routes.length > 0) {
    	var component = routes[0].components.default;
    	if(component instanceof Function) {
    		//动态组件
    		component().then(({default: comp}) => {
    			Vue.component(routerName, comp);
    			callback(true);
    		});
    	} else {
    		Vue.component(routerName, component);
    		callback(true);
    	}
    } else {
    	callback(false);
    }
}

export const alert = (msg, callback, loading) => {	
	$.alert(msg, callback, loading);
}

export const info = (msg, callback, loading) => {	
	$.info(msg, callback, loading);
}

export const success = (msg, callback, loading) => {	
	$.success(msg, callback, loading);
}

export const error = (msg, callback, loading) => {	
	$.error(msg, callback, loading);
}

export const confirm = (msg, callback, loading) => {
	$.confirm(msg, callback, loading);
}

export const mwarning = function() {	
	$.mwarning.apply(null, arguments);
}

export const minfo = function() {	
	$.minfo.apply(null, arguments);
}

export const msuccess = function() {	
	$.msuccess.apply(null, arguments);
}

export const merror = function() {	
	$.merror.apply(null, arguments);
}

export const mloading = function() {	
	$.mloading.apply(null, arguments);
}

export const showGlobalError = (msg, callback) => {
	$.showGlobalError(msg, callback);
}

export const fit = (container, dataWithHeight) => {
	$.fit(container, dataWithHeight);
}

export const bind = (obj) => {
	for(name in $) {
		$[name] = $[name].bind(obj);
	}
}

export const location = (router, params = {}, embed='') => {
	$.location(router, params, embed);
}

export const init = () => {
	$.init();
}

export const uninit = () => {
	$.uninit();
}

export const setting = (name, value) => {
	if(value) {
		if(typeof(value) == 'string') {
			setUserSetting(name, value);
		} else if(typeof(value) == 'function') {
			const callback = value;
			getUserSetting(name, (returnValue) => {
				callback(returnValue);
			});
		}
	} else {
		setUserSetting(name);
	}
}

export const settings = (callback) => {
	getUserSettings(callback);
}

export const roles = (roles, callback) => {
	hasRoles(roles, (res) => {
		if(res.success) {
			callback(true, res.data);
		} else {
			callback(false);
		}
	});
}

export const perms = (perms, callback) => {
	hasPerms(perms, (res) => {
		if(res.success) {
			callback(true, res.data);
		} else {
			callback(false);
		}
	});
}

export const dict = (opts, callback) => {
	var params = {
		values:[],
		children:false
	}
	extend(params, opts);
	if(params.values instanceof String) {
		params.values = [params.values];
	}
	var cache = getDict(params.values, params.children);
	if(cache) {
		callback(true, cache);
		return;
	}
	getSimpleDict(params, (res) => {
		if(res.success) {
			setDict(params.values, params.children, res.data);
			callback(true, res.data);
		} else {
			callback(false);
		}
	});
}

export const dicts = (opts, callback) => {
	var params = {
		values:{},
		children:false
	}
	extend(params, opts);
	for(name in params.values) {
		if(typeof(params.values[name]) == 'string') {
			params.values[name] = [params.values[name]];
    	}
	}
	var cache = getDicts(params.values, params.children);
	if(!Object.keys(params.values).length) {
		callback(true, cache);
		return;
	}
	getMultiDicts(params, (res) => {
		if(res.success) {
			setDicts(params.values, params.children, res.data);
			extend(res.data, cache);
			callback(true, res.data);
		} else {
			callback(false);
		}
	});
}

export const createWindow = (options) => {
	$.createWindow(options);
}

export const fillRouter = (router) => {
	return router.substring(0, 1) == "/" ? router : "/" + router;
}

export const exit = () => {
	$.exit();
}

export const nextFrameId = () => {
	return ++ frameId;
}

export const currentFrameId = () => {
	return frameId;
}

export const dateRender = (h, params) => {
	var value = params.row[params.column.key];
    return h('span', {}, value ? value.substring(0, 19) : value);
}

export const yesOrNoRender = (h, params) => {
	return $.yesOrNoRender(h, params);
}

export const EMBED_ROUTER = '/sys/embed/:id';

export const EMBED_NAME = 'SysEmbed';

export const IFRAME_ROUTER = '/sys/iframe/:id';

export const IFRAME_NAME = 'SysIframe';

export const isEmbed = (router) => {
	var start = router.substring(0, 7);
	if(start == 'http://' || start == 'https:/') {
		return true;
	}
	var end = router.substring(router.length - 5);
	if(end == '.html') {
		return true;
	}
	end = router.substring(router.length - 4);
	if(end == '.htm') {
		return true;
	}
	end = router.substring(router.length - 3);
	if(end == '.js') {
		return true;
	}
	return false;
}

export const getRouterName = (router) => {
	var array = router.split("/");
	var result = "";
	for(var i=0; i<array.length; i++) {
		result += upcaseFirstChar(array[i]);
	}
	return result;
}

export const profile = () => {
	$.profile();
}

export const toUrl = (uri) => {
	if(uri) {
		if(uri.substring(0, 1) == '/') {
			return process.env.VUE_APP_BASE_URL + uri;
		}
	}
	return uri;
}

export const toDownLoadUrl = (id) => {
	return toUrl(`${URI_DOWNLOAD}?id=${id}`);
}

export const setCurrentMenuType = (menuType) => {
	currentMenuType = menuType;
}

export const treeFilter = (tree, filter) => {
	var results = [];
	var childrenResults = [];
	var result = tree.filter((item, index, arr) => {
		if(item.children && item.children.length) {
			const results = treeFilter(item.children, filter);
			if(results) {
				if(results instanceof Array) {
					childrenResults = childrenResults.concat(results);
				} else {
					childrenResults.push(results);
				}
			}
		}
		return filter(item, index, arr);
	});
	if(result) {
		if(result instanceof Array) {
			results = results.concat(result);
		} else {
			results.push(result);
		}
	}
	if(childrenResults.length) {
		results = results.concat(childrenResults);
	}
	return results;
}

export default {
	bind,
	toUrl,
	fillRouter,
	nextFrameId,
	currentFrameId,
	setCurrentMenuType,
	alert,
	info,
	success,
	error,
	showGlobalError,
	location,
	init,
	uninit,
	minfo,
	msuccess,
	merror,
	mwarning,
	mloading,
	confirm,
	dateRender,
	yesOrNoRender,
	isEmbed,
	getRouterName,
	setting,
	settings,
	createWindow,
	perms,
	roles,
	dict,
	dicts,
	profile,
	extend, 
	extendHtml, 
	htmlToText, 
	each, 
	deleteNullValue, 
	upcaseFirstChar
}